#include <string>
#include "Peer.h"
#include "Common.h"
#include "File.h"

using namespace std;

void displayHelp(){
    cout<<"Possible commands:"<<endl;
    cout<<"join - join the network"<<endl;
    cout<<"query - query and display the current state of sharing"<<endl;
    cout<<"insert <filename with absolute directory> - insert this file to share"<<endl;
    cout<<"leave - leave the network"<<endl;
    cout<<"exit - exit the program"<<endl;
    cout<<"help - display this again"<<endl;
    return;
}

void displayError(string message, int status){
    printf("ERROR:%s TYPE 0x%x\n", message.c_str(), status);
}

int main(int argc, char *argv[]){
    // output possible commands
    cout<<"========================"<<endl;
    cout<<"Welcome to FileShare!"<<endl;
    cout<<"June 1st, 2012"<<endl;
    cout<<"By Michael Liu, Xin Zhao"<<endl;
    cout<<"========================"<<endl;
    displayHelp();

    string myIP = "";
    int myPort = PORT;
    int myCapacity = 0;

    if (argc == 4) {
        myIP += argv[1];
        myPort = atoi(argv[2]);
        myCapacity = atoi(argv[3]);
    } else {
        cerr << "incorrect format: ./<executable> <ip> <port>" << endl;
        return -1;
    }

    // initialize stuff here.
    Peer *localPeer = new Peer(myIP, myPort, myCapacity);
    int status = SAFE;

    // commandline interface
    // Available commands: insert, query, join, leave, exit.

    bool EXIT = false;
    
    while(!EXIT){
        printf(">");
        string input;
        getline(cin,input);
        // parse input
        if(input == "join"){
            DBG_PRINTF(("join was called\n"));
            status = localPeer->join();
            if (status < 0) displayError("Join failed!", status);
        } else if(input == "query"){
            DBG_PRINTF(("query was called\n"));
            localPeer->display();
        } else if(input.substr(0,6) == "insert"){
            DBG_PRINTF(("insert was called\n"));
            string file = "";
            try{
                file = input.substr(7,input.length());
            } catch (...) { 
                // this is only here because if the command insert is not followed by a parameter, the substr function will throw an exception. 
            } 
            if(file.empty()){
                displayError("Please provide a file to insert!", errNoFileFound);
            } else {
                // second param is provided. do useful work here.
                DBG_PRINTF(("FILE NAME %s\n", file.c_str()));
                status = localPeer->insert(file);
                if(status == errNoFileFound)
                {
                    displayError(file+" was not found!", status);
                } else if (status == errFileAlreadyExist) {
                    displayError(file+" is already in the network!", status);
                }
            } 
        } else if(input == "leave"){
            status = localPeer->leave();
            if(status == errNotConnected)
            {
                displayError("Not connected to the network. Abort leave.", status);
            }
            DBG_PRINTF(("leave was called\n"));
            // call leave to change state, and broadcast to network that I am leaving
            // tell thread to close all sockets
            // clean up with the threads
        } else if(input == "exit"){
            localPeer->leave();
            printf("Exiting the Program...\n");
            printf("Goodbye!\n");
            EXIT = true;
        } else if(input == "help"){
            displayHelp();
        } else {
            displayError("This command does not exists. Please type help to display all possible commands.", errUnknownWarning);
        }


        // 


        // break out and exit when exit.
        // depending on input call functions.

        // once joined, cannot call join again

        // once left, cannot call leave again

    }

    // cleanup
    delete localPeer;

    return 0;
}
